package cn.edu.scau.sec.rw.model.pro_manage.simulation;

import cn.edu.scau.sec.rw.model.device_manage.Device.DeviceForProcess;
import cn.edu.scau.sec.rw.model.device_manage.Device.Device_Pcb;
import cn.edu.scau.sec.rw.model.pro_manage.Process;
import cn.edu.scau.sec.rw.model.pro_manage.ProcessControl;
import cn.edu.scau.sec.rw.model.pro_manage.threadExe.DeviceThread;

import java.util.List;

/**
 * 模拟中断
 */
public class Interrupt {

    private static ProcessControl processControl = new ProcessControl();

    /**
     * 程序结束：在屏幕上输出 x 的值，调用“进程撤销原语”撤销进程，然后进行进程调度
     * @param process
     */
    public static void programInterrupt(Process process) {
        process.getPCB().getRegister().getPSW()[0] = 0;
        processControl.destroyProcess(process);
    }

    /**
     * 时间片用尽：将正在运行进程 的 CPU 现场保存在进程控制块中，然后进行进程调度
     * @param process
     */
    public static void timeSliceInterrupt(Process process) {
        //cpu.getProcess().getPCB().setRegister(cpu.getRegister());
        processControl.blockProcess(process);
        process.getPCB().getRegister().getPSW()[1] = 0;
        processControl.awakeProcess(process);
    }

    /**
     * I/O中断：将输入输出完成的进程唤醒，将等待该设备的进程唤醒。
     * 阻塞原因分：IO中断、等待IO，执行IO，IO完成
     * @param process
     */
    public static void IOInterrupt(Process process) {

        switch (process.getPCB().getBlockReason()) {
            case "IO中断" :
                process.getPCB().setBlockReason("等待IO");
                processControl.blockProcess(process);
                //说明：
                //确定好执行时间 和 完成时间
                //只有在ifIo==1
                //这两个字段才有效
                Device_Pcb pcb= new DeviceForProcess().ArriveOneProcess(new Device_Pcb(Clock.getSystemClock(), process.getDeviceTime(),
                        process.getDeviceName(), String.valueOf(process.getPCB().getProId())));
                process.getPCB().ifIO=1;
                process.getPCB().StartIO=pcb.Start_IO;
                process.getPCB().EndIO=pcb.EndIO;
                processControl.blockProcess(process);
                Process.getIOWaitProcesses().add(process);

                break;

            case "等待IO" :
                //System.out.println("3s433t2532");
                //伪代码：
                Integer Tc = Clock.getSystemClock();  //获取当前系统时钟 记作Tc
                // 和process.getPCB.StartIO 比较
                // 大于等于时 就更新状态为 执行IO
                if (process.getPCB().StartIO <= Tc) {
                    process.getPCB().setBlockReason("执行IO");
                }
                Process.getIOWaitProcesses().add(process);
                break;

            case "执行IO":
                //伪代码：
                Integer Ta = Clock.getSystemClock();//获取当前系统时间 记作Ta
                //和process.getPCB().EndIO 比较
                //大于等于时 跟新状态为 IO完成
                if (process.getPCB().EndIO <= Ta) {
                    process.getPCB().setBlockReason("IO完成");
                    Process.getIOFinishProcesses().add(process);
                } else {
                    Process.getIOWaitProcesses().add(process);
                }

                break;

            case "IO完成" :
                processControl.awakeProcess(process);
                process.getPCB().getRegister().getPSW()[2] = 0;
                break;
        }
    }
}
